package generator;

import org.eclipse.uml2.uml.Element;
import java.util.Properties;

public class JpaEntityTemplateClass extends BaseTemplateClass {

	protected ClassCommentTemplateClass classCommentTemplateClass;
	protected JpaEntityMappedSuperclassTemplateClass jpaEntityMappedSuperclassTemplateClass;
	protected JpaEntityKeyTemplateClass jpaEntityKeyTemplateClass;
	protected JpaEntityConstructorsTemplateClass jpaEntityConstructorsTemplateClass;
	protected JpaEntityAccessorsTemplateClass jpaEntityAccessorsTemplateClass;
	protected JpaEntityAssociationsTemplateClass jpaEntityAssociationsTemplateClass;

	public JpaEntityTemplateClass(Properties properties) {
		super(properties);
		classCommentTemplateClass = new ClassCommentTemplateClass(properties);
		jpaEntityMappedSuperclassTemplateClass = new JpaEntityMappedSuperclassTemplateClass(properties);
		jpaEntityKeyTemplateClass = new JpaEntityKeyTemplateClass(properties);
		jpaEntityConstructorsTemplateClass = new JpaEntityConstructorsTemplateClass(properties);
		jpaEntityAccessorsTemplateClass = new JpaEntityAccessorsTemplateClass(properties);
		jpaEntityAssociationsTemplateClass = new JpaEntityAssociationsTemplateClass(properties);
	}

	public boolean isProcessable() {
		return isEntity();
	}

	public void setElement(Element ele) {
		this.element = ele;
		returningString = new StringBuilder();
		classCommentTemplateClass.setElement(ele);
		jpaEntityMappedSuperclassTemplateClass.setElement(ele);
		jpaEntityKeyTemplateClass.setElement(ele);
		jpaEntityConstructorsTemplateClass.setElement(ele);
		jpaEntityAccessorsTemplateClass.setElement(ele);
		jpaEntityAssociationsTemplateClass.setElement(ele);
	}

	protected String _returning() {
		returningString.append("package ");
		returningString.append(getEntityPackage());
		returningString.append(";\n\nimport javax.persistence.*;\n\n");
		if (classCommentTemplateClass.isProcessable()) {
			returningString.append(classCommentTemplateClass.returning());
		}
		returningString.append("\n@SuppressWarnings(\"serial\")\n@Entity\n@Table(name = \"");
		returningString.append(getName(element));
		returningString.append("\")\n");
		if (jpaEntityMappedSuperclassTemplateClass.isProcessable()) {
			returningString.append(jpaEntityMappedSuperclassTemplateClass.returning());
		}
		returningString.append("\npublic class ");
		returningString.append(getName(element));
		returningString.append(" ");
		returningString.append(getExtensionSyntax());
		returningString.append(" implements java.io.Serializable {\n\t");
		if (jpaEntityKeyTemplateClass.isProcessable()) {
			returningString.append(jpaEntityKeyTemplateClass.returning());
		}
		returningString.append("\n\t");
		if (jpaEntityConstructorsTemplateClass.isProcessable()) {
			returningString.append(jpaEntityConstructorsTemplateClass.returning());
		}
		returningString.append("\n\t");
		if (jpaEntityAccessorsTemplateClass.isProcessable()) {
			returningString.append(jpaEntityAccessorsTemplateClass.returning());
		}
		returningString.append("\n\t");
		if (jpaEntityAssociationsTemplateClass.isProcessable()) {
			returningString.append(jpaEntityAssociationsTemplateClass.returning());
		}
		returningString.append("\n}");

		return returningString.toString();
	}
	
	/**
	 * Returns the package for the entity based on the 'basePackage' property and the
	 * current package of the element.
	 */
	public String getEntityPackage() {
		String value = properties.getProperty("basePackage");
		value += "." + ((org.eclipse.uml2.uml.Class)element).getPackage().getName();
		return value;
	}

	/**
	* Si la clase extiende a otra, retorna la sintaxis correspondiente.
	*/
	public String getExtensionSyntax() {
		if (isExtending()) {
			return "extends " + getSuperclass();
		}
		return "";
	}

	/**
	* Indica si el elemento es una clase con estereotipo "Entity"
	* @param element
	* @return
	*/
	public boolean isEntity() {
		return hasStereotype(element, "Entity");
	}

	/**
	* Indica si la clase extiende a alguna otra
	* @param elt
	* @return
	*/
	public boolean isExtending() {
		return getSuperclass().length() > 0;
	}

	/**
	* Retorna el nombre de la superclase o un string vacío si no tiene.
	* @param elt
	* @return
	*/
	public String getSuperclass() {
		if (element instanceof org.eclipse.uml2.uml.Class) {
			org.eclipse.uml2.uml.Class cls = (org.eclipse.uml2.uml.Class)element;
			if (cls.getSuperClasses().size() == 1) {
				return cls.getSuperClasses().get(0).getName();
			}
		}
		return "";
	}
		
	public void createFile() {
		String filePath = "src/" + toPath(getEntityPackage());
		String fileName = filePath + "/" + getName(element) + ".java";
		java.io.File dirs = new java.io.File(filePath);
		java.io.File file = new java.io.File(fileName);
		java.io.BufferedWriter fw = null;
		try {
			dirs.mkdirs();
			file.createNewFile();
			fw = new java.io.BufferedWriter(new java.io.FileWriter(file));
			fw.write(returningString.toString());
		} catch (java.io.IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fw.flush();
				fw.close();
			} catch (java.io.IOException ioe) {
			}
		}
	}
	
}